/*! \file
 * \brief Enter a brief description here.
 *
 * Enter a detailed description here. (optional)
 * \author Author (Ivo Wingelaar)
 * \date Date (2011)
 * \version Version (0.0.1)
 * \copyright Copyright (GNU LGPL v3)
 */

#ifndef __LYNX_IMAGE_C_HPP_INCLUDED__
#define __LYNX_IMAGE_C_HPP_INCLUDED__

#include "LynxImage.hpp"

namespace Lynx
{

//! IImage implementation with a lot of special image operations for
//! 16 bit A1R5G5B5/32 Bit A8R8G8B8 images, which are used by the SoftwareDevice.
class Image_C : public Image
{
public:

    //! constructor from raw image data
    /** \param useForeignMemory: If true, the image will use the data pointer
    directly and own it from now on, which means it will also try to delete [] the
    data when the image will be destructed. If false, the memory will by copied. */
    Image_C(E_COLOR_FORMAT format, const Myth::Math::Vector2u size, void* data, bool ownForeignMemory=true, bool deleteMemory = true);

    //! constructor for empty image
    Image_C(E_COLOR_FORMAT format, const Myth::Math::Vector2u size);

    //! destructor
    virtual ~Image_C();

    //! Lock function.
    virtual void* get_pointer();

    //! Returns width and height of image data.
    virtual Myth::Math::Vector2u get_dimension() const;

    //! Returns bits per pixel.
    virtual uint32_t get_bits_per_pixel() const;

    //! Returns bytes per pixel
    virtual uint32_t get_bytes_per_pixel() const;

    //! Returns image data size in bytes
    virtual uint32_t get_image_data_size_in_bytes() const;

    //! Returns image data size in pixels
    virtual uint32_t get_image_data_size_in_pixels() const;

    //! returns mask for red value of a pixel
    virtual uint32_t get_red_mask() const;

    //! returns mask for green value of a pixel
    virtual uint32_t get_green_mask() const;

    //! returns mask for blue value of a pixel
    virtual uint32_t get_blue_mask() const;

    //! returns mask for alpha value of a pixel
    virtual uint32_t get_alpha_mask() const;

    //! returns a pixel
    virtual Color get_pixel(uint32_t x, uint32_t y) const;

    //! sets a pixel
    virtual void set_pixel(uint32_t x, uint32_t y, const Color color, bool blend = false);

    //! returns the color format
    virtual E_COLOR_FORMAT get_color_format() const;

    //! returns pitch of image
    virtual uint32_t get_pitch() const;

    virtual void copy_to_scaling(void* target, uint32_t width, uint32_t height, E_COLOR_FORMAT format = ECF_A8R8G8B8, uint32_t pitch = 0);

    virtual void copy_to_scaling(Image* target);

    virtual void copy_to(Image* target, const Myth::Math::Vector2i& pos = Myth::Math::Vector2i(0,0));

    virtual void copy_to(Image* target, const Myth::Math::Vector2i& pos, const Myth::Math::Rectanglei& sourceRect, const Myth::Math::Rectanglei* clipRect = 0);

    virtual void copy_to_with_alpha(Image* target, const Myth::Math::Vector2i& pos, const Myth::Math::Rectanglei& sourceRect, const Color color, const Myth::Math::Rectanglei* clipRect = 0);

    virtual void copy_to_scaling_box_filter(Image* target, int32_t bias = 0, bool blend = false);

    //! fills the surface with black or white
    virtual void fill(const Color color);
private:
    //! assumes format and size has been set and creates the rest
    void init_data();

    inline Color get_pixel_box(int32_t x, int32_t y, int32_t fx, int32_t fy, int32_t bias) const;

    uint8_t* mData;
    Myth::Math::Vector2u mSize;
    uint32_t mBytesPerPixel;
    uint32_t mPitch;
    E_COLOR_FORMAT mFormat;

    bool mDeleteMemory;
};

} // namespace Lynx

#endif // __LYNX_IMAGE_C_HPP_INCLUDED__

